﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using VNet.VisiSuite.Common.Resource;
using VNet.VisiSuite.Service.Contact.Message.Item;

namespace VNet.VisiSuite.VisiAdmin.Models
{
    public class ReasonCodeModel : ComparableBaseModel<ReasonCodeModel>, IDataErrorInfo
    {

        private int _reasonCodeId;
        public int ReasonCodeId
        {
            get { return _reasonCodeId; }
            set
            {
                _reasonCodeId = value;
                OnPropertyChanged("ReasonCodeId");
            }
        }

        private int _areaId;
        public int AreaId
        {
            get { return _areaId; }
            set
            {
                _areaId = value;
                OnPropertyChanged("AreaId");
            }
        }

        private ReasonCodeModel _parent;
        public ReasonCodeModel Parent
        {
            get { return _parent; }
            set
            {
                if (_parent == value) return;
                _parent = value;

                ParentId = _parent != null ? (int?)_parent.ReasonCodeId : null;

                OnPropertyChanged("Parent");
            }
        }

        private int? _parentId;
        [Category("Properties")]
        [DisplayName("Parent Reason Code")]
        [Description("Parent Reason Code.")]
        public int? ParentId
        {
            get { return _parentId; }
            set
            {
                if (_parentId != value)
                {
                    _parentId = value;
                    OnPropertyChanged("ParentId", true);
                }
            }
        }

        private ReasonCodeModel _link;
        public ReasonCodeModel Link
        {
            get { return _link; }
            set
            {
                if (_link == value) return;
                _link = value;

                LinkId = _link != null ? (int?)_link.ReasonCodeId : null;

                OnPropertyChanged("Link");
            }
        }

        private int? _link_id;
        [Category("Properties")]
        [DisplayName("Linked Reason Code")]
        [Description("Linked Reason Code.")]
        public int? LinkId
        {
            get { return _link_id; }
            set
            {
                if (_link_id != value)
                {
                    _link_id = value;
                    OnPropertyChanged("LinkId", true);
                }
            }
        }


        private RollupDefinitionModel _rollupDefinition;
        
        public RollupDefinitionModel RollupDefinition
        {
            get { return _rollupDefinition; }
            set
            {
                if (_rollupDefinition == value) return;
                _rollupDefinition = value;

                RollupDefinitionId = _rollupDefinition != null ? (int?)_rollupDefinition.RollupDefinitionId : null;
                RollupDefinitionDescription = _rollupDefinition != null ? _rollupDefinition.Description : null;

                OnPropertyChanged("RollupDefinition");
            }
        }

        private string _rollupDefinitionDescription;
        public string RollupDefinitionDescription
        {
            get { return _rollupDefinitionDescription; }
            set
            {
                if (_rollupDefinitionDescription == value) return;
                _rollupDefinitionDescription = value;
                OnPropertyChanged("RollupDefinitionDescription");
            }
        }

        private int? _rollupDefinitionId;
        [Category("Properties")]
        [DisplayName("Roll up Definition")]
        [Description("Roll up Definition.")]
        public int? RollupDefinitionId
        {
            get { return _rollupDefinitionId; }
            set
            {
                if (_rollupDefinitionId != value)
                {
                    _rollupDefinitionId = value;
                    OnPropertyChanged("RollupDefinitionId", true);
                }
            }
        }

        private int _level;
        public int Level
        {
            get { return _level; }
            set
            {
                _level = value;
                OnPropertyChanged("Level");
            }
        }

        public bool _scrap = false;
        public bool Scrap
        {
            get { return _scrap; }
            set { _scrap = value; }
        }

        private string _description;

        [Category("Properties")]
        [DisplayName("Description")]
        [Description("Reason Code Description.")]
        public string Description
        {
            get { return _description; }
            set
            {
                _description = value;
                OnPropertyChanged("Description", true);
                OnPropertyChanged("DescriptionWithLink", true);
            }
        }

        public string DescriptionWithLink
        {
            get
            {
                string val = _description;
                if (LinkId.HasValue)
                    val += "*";
                return val;
            }
        }

        private string _createdBy;
        [Category("Update History")]
        [DisplayName("Created By")]
        [Description("User who created the reason code in VisiAdmin.")]
        [ReadOnly(true)]
        public string CreatedBy
        {
            get { return _createdBy; }
            set
            {
                _createdBy = value;
                OnPropertyChanged("CreatedBy");
            }
        }

        private string _createdDate;
        [Category("Update History")]
        [DisplayName("Created On")]
        [Description("Date when the reason code was created in VisiAdmin.")]
        [ReadOnly(true)]
        public string CreatedDate
        {
            get { return _createdDate; }
            set
            {
                _createdDate = value;
                OnPropertyChanged("CreatedDate");
            }
        }

        private string _lastUpdatedBy;
        [Category("Update History")]
        [DisplayName("Updated By")]
        [Description("User who last edited the reason code in VisiAdmin.")]
        [ReadOnly(true)]
        public string LastUpdatedBy
        {
            get { return _lastUpdatedBy; }
            set
            {
                _lastUpdatedBy = value;
                OnPropertyChanged("LastUpdatedBy");
            }
        }

        private string _lastUpdatedDate;
        [Category("Update History")]
        [DisplayName("Updated On")]
        [Description("Date when the reason code was last edited in VisiAdmin.")]
        [ReadOnly(true)]
        public string LastUpdatedDate
        {
            get { return _lastUpdatedDate; }
            set
            {
                _lastUpdatedDate = value;
                OnPropertyChanged("LastUpdatedDate");
            }
        }

        private bool _ignore_visibox_events;
        [Category("Properties")]
        [DisplayName("Ignore VisiBox Events")]
        [Description("Ignore VisiBox Events.")]
        public bool IgnoreVisiBoxEvents
        {
            get { return _ignore_visibox_events; }
            set
            {
                _ignore_visibox_events = value;
                OnPropertyChanged("IgnoreVisiBoxEvents", true);
            }
        }

        private bool _hide_children;
        [Category("Properties")]
        [DisplayName("Hide Child Nodes")]
        [Description("Hide Child Nodes.")]
        public bool HideChildren
        {
            get { return _hide_children; }
            set
            {
                _hide_children = value;
                OnPropertyChanged("HideChildren", true);
            }
        }

        private short? _flash_interval;
        [Category("Properties")]
        [DisplayName("Flash Delay")]
        [Description("Flash Delay.")]
        public short? FlashDelay
        {
            get { return _flash_interval; }
            set
            {
                _flash_interval = value;
                OnPropertyChanged("FlashDelay", true);
            }
        }

        private bool _displayInDowntimeChart;
        [Category("Properties")]
        [DisplayName("Display In Downtime Chart")]
        [Description("Display In Downtime Chart.")]
        public bool DisplayInDowntimeChart
        {
            get { return _displayInDowntimeChart; }
            set
            {
                _displayInDowntimeChart = value;
                OnPropertyChanged("DisplayInDowntimeChart", true);
            }
        }

        private bool _ignoreInOeeCalc;
        [Category("Properties")]
        [DisplayName("Ignore In Oee Calc")]
        [Description("Ignore In Oee Calculation.")]
        public bool IgnoreInOeeCalc
        {
            get { return _ignoreInOeeCalc; }
            set
            {
                _ignoreInOeeCalc = value;
                OnPropertyChanged("IgnoreInOeeCalc", true);
            }
        }

        private bool _ignoreInWaitingCalc;
        [Category("Properties")]
        [DisplayName("Ignore In Waiting Calc")]
        [Description("Ignore In Waiting Calculation.")]
        public bool IgnoreInWaitingCalc
        {
            get { return _ignoreInWaitingCalc; }
            set
            {
                _ignoreInWaitingCalc = value;
                OnPropertyChanged("IgnoreInWaitingCalc", true);
            }
        }

        private ReasonCodeItem.ReasonCodeCategory _category;
        [Category("Properties")]
        [DisplayName("Category")]
        [Description("Category.")]
        public ReasonCodeItem.ReasonCodeCategory Category
        {
            get { return _category; }
            set
            {
                _category = value;
                OnPropertyChanged("ReasonCodeCategory", true);
            }
        }

        private ObservableCollection<ReasonCodeModel> _children;
        public ObservableCollection<ReasonCodeModel> Children
        {
            get { return _children; }
            set
            {
                if (_children == value) return;
                _children = value;
                OnPropertyChanged("Children");
            }
        }



        private ReasonCodeItem.ShopClockEventEnum _shop_clock_event;
        [Category("Properties")]
        [DisplayName("Shop Clock Event")]
        [Description("Shop clock event.")]
        public ReasonCodeItem.ShopClockEventEnum ShopClockEvent
        {
            get { return _shop_clock_event; }
            set
            {
                _shop_clock_event = value;
                OnPropertyChanged("ShopClockEvent", true);
            }
        }

        #region IDataErrorInfo Implementation

        public string Error
        {
            get { return string.Empty; }
        }

        public string this[string columnName]
        {
            get
            {
                if (!ShouldValidate)
                    return string.Empty;

                if (columnName == "Description" && string.IsNullOrWhiteSpace(Description))
                    return ValidationMessages.DescriptionRequired;

                return string.Empty;
            }
        }

        #endregion

        #region Override Equals methods
        public bool Equals(ReasonCodeModel other)
        {

            if (ReferenceEquals(null, other))
                return false;
            if (ReferenceEquals(this, other))
                return true;

            return 
                ReasonCodeId == other.ReasonCodeId
                && string.Equals(Description, other.Description)
                && (ParentId ?? 0) == (other.ParentId ?? 0)
                && (LinkId ?? 0) == (other.LinkId ?? 0)
                && (RollupDefinitionId ?? 0) == (other.RollupDefinitionId ?? 0)
                && IgnoreVisiBoxEvents == other.IgnoreVisiBoxEvents
                && Category == other.Category
                && HideChildren == other.HideChildren
                && FlashDelay == other.FlashDelay
                && IgnoreInOeeCalc == other.IgnoreInOeeCalc
                && IgnoreInWaitingCalc == other.IgnoreInWaitingCalc
                && DisplayInDowntimeChart == other.DisplayInDowntimeChart
                && ShopClockEvent == other.ShopClockEvent;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
                return false;
            if (ReferenceEquals(this, obj))
                return true;
            if (obj.GetType() != this.GetType())
                return false;
            return Equals((ReasonCodeModel)obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return ReasonCodeId.GetHashCode();
            }
        }
        #endregion

    }
}
